package multi_thread.master.executors;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author Cheng Jun
 * Description: 使用 submit 提交 Runnable 或 Callable时，源码中都会进行一次封装，
 * 将其封装成 RunnableFuture的是对象ftask，然后 execute(ftask);
 * 所以如果要移除 任务，remove 封装后的 ftask。即 excute 执行了什么，remove 移除什么
 * @version 1.0
 * @date 2022/5/22 18:07
 */
public class RemoveRunnableFutureExample {

    public static void main(String[] args) throws InterruptedException {
        // 设置成 1，方便调试
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
        List<Runnable> taskList = new ArrayList<>();
        List<Future<?>> futureList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Runnable task = () -> {
                try {
                    // 方便调试
                    TimeUnit.HOURS.sleep(4);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 当前线程已经运行");
            };

            // 配合演示 ThreadPoolExecutor的remove 方法
            // fixedThreadPool.execute(task);
            // taskList.add(task);

            // 配合演示 ThreadPoolExecutor的remove 和 purge 方法
            Future<?> future = fixedThreadPool.submit(task);
            futureList.add(future);

            taskList.add(task);
        }
        // 保证任务全部入列
        TimeUnit.SECONDS.sleep(2);

        for (Runnable task : taskList) {
            // 使用 execute 提交的任务，使用remove 方法删除
            // 尚未开始的任务将会被 remove，已经开始的任务无法remove
            // 如果想 终止正在运行的的任务，可以先取消任务，然后 purge
            // System.out.println(((ThreadPoolExecutor) fixedThreadPool).remove(task));
        }

        // submit 提交的任务，未运行的任务使用remove方法删除，但是注意要使用 submit方法的返回值作为 remove的参数
        for (Future<?> future : futureList) {
            System.out.println(((ThreadPoolExecutor) fixedThreadPool).remove((RunnableFuture<Void>) future));
        }

        // // 取消 队列中的任务，mayInterruptIfRunning 参数，如果想中断正在运行的任务，设置成true，如果不想中断正在运行的任务，设置成false
        // futureList.forEach(future -> future.cancel(true));
        // // Tries to remove from the work queue all Future tasks that have been cancelled
        // // 试图从工作队列中删除所有已取消的Future任务
        // ((ThreadPoolExecutor) fixedThreadPool).purge();

        fixedThreadPool.shutdown();
    }
}
